﻿using System;
using DragonsEyeAdventure.Utilities;

/*
 * Author: Nathaniel Edgar
 * Contributors:
 * File Version: v0.6
 * 
 * Copyright (C) 2013 Nathaniel Edgar
 * For full copyright information, please see the project README
 */

namespace DragonsEyeAdventure.Utilities
{
    /// <summary>
    /// Utility class for loading different menus
    /// </summary>
    abstract class Menus
    {
        #region Position Variables
        private static int center = Program.width / 2;  //Center of the window; used so often it's a static int
        //Main title offsets
        private static int mainTitleX = center - (mainTitle.Length / 2);
        private static int mainTitleY = Program.height / 4;
        //Sub-title offsets
        private static int subTitleX = center - (subTitle.Length / 2);
        private static int subTitleY = (Program.height / 4) + 1;
        #endregion

        #region Text Variables
        private const string mainTitle = "The Dragon's Eye";
        private const string subTitle = "A Text Adventure";
        //The newlines are from experimentation: DO NOT CHANGE LIGHTLY
        private const string aboutMessage = "The Dragon's Eye: A Text Adventure\nCopyright (C) 2013 Nathaniel Edgar\n\n" +
            "This program comes with ABSOLUTELY NO WARRANTY. Also, this  is free software, and you are welcome to redistribute it\n" +
            "under certain conditions. For details, please see the\nproject README.";
        #endregion

        #region Menu Variables
        private static string[] mainMenuOptions = new string[] { "Play", "Options", "Info", "Exit" };
        private static string[] pauseMenuOptions = new string[] { "Resume", "Options", "Main Menu" };
        private static string[] optionMenuSettings = new string[] { "NOT IMPLEMENTED" };
        private static int selectedOption = -1;
        #endregion

        #region Drawing Methods
        /// <summary>
        /// Draws the main menu
        /// </summary>
        public static void drawMainMenu()
        {
            //Clear the screen
            Console.Clear();

            //Set the position of the main title and print
            Console.SetCursorPosition(mainTitleX, mainTitleY);
            Console.Write(mainTitle);
            //Set the position of the sub-title and print
            Console.SetCursorPosition(subTitleX, subTitleY);
            Console.Write(subTitle);

            //Print the outline
            Printer.printBox(mainTitleX - 2, mainTitleY - 1, mainTitle.Length + 4, 4);

            //Print the options
            for (int options = 0; options != mainMenuOptions.Length; options++)
            {
                //Set offsets
                int xOffset = center - (mainMenuOptions[options].Length / 2);
                int yOffset = ((Program.height / 2) - (mainMenuOptions.Length / 2)) + (options - 1);

                //Draw the option
                Console.SetCursorPosition(xOffset, yOffset);
                Console.Write(mainMenuOptions[options]);
            }

            //Set up and draw the selector
            selectedOption = 0;
            drawSelector(mainMenuOptions);
        }

        /// <summary>
        /// Draws the info submenu
        /// </summary>
        public static void drawInfo()
        {
            //Clear the screen and set to submenu status
            Console.Clear();
            Program.currMenu = Program.EMenu.Submenu;

            //Print the info in the center of the screen
            Printer.printInBox(Program.width - 20, 10, 9, aboutMessage);
        }

        /// <summary>
        /// Draws the options submenu
        /// </summary>
        public static void drawOptions()
        {
            //Clear the screen and set to submenu status
            Console.Clear();
            Program.currMenu = Program.EMenu.Submenu;

            //Print the settings selections
            for (int options = 0; options != optionMenuSettings.Length; options++)
            {
                //Set the offsets
                int xOffset = center - (optionMenuSettings[options].Length / 2);
                int yOffset = ((Program.height / 2) - (optionMenuSettings.Length / 2)) + (options - 2);

                //Draw the options
                Console.SetCursorPosition(xOffset, yOffset);
                Console.Write(optionMenuSettings[options]);
            }
        }

        /// <summary>
        /// Draws the 'selector': the two arrows (> and <) that show the selected option
        /// </summary>
        /// <param name="menu">Menu to apply change to</param>
        public static void drawSelector(string[] menu)
        {
            //Set offsets
            int xOffsetLeft = center - 7;
            int xOffsetRight = center + 6;
            int yOffset = ((Program.height / 2) - (menu.Length / 2)) + (selectedOption - 1);

            //Draw the selector
            Console.SetCursorPosition(xOffsetLeft, yOffset);
            Console.Write(">");
            Printer.setCursorX(xOffsetRight);
            Console.Write("<");
        }
        
        /// <summary>
        /// Deletes the currently drawn selector
        /// </summary>
        /// <param name="menu">Menu to apply change to</param>
        public static void deleteSelector(string[] menu)
        {
            //Set offsets
            int xOffsetLeft = center - 7;
            int xOffsetRight = center + 6;
            int yOffset = ((Program.height / 2) - (menu.Length / 2)) + (selectedOption - 1);

            //Delete the selector
            Console.SetCursorPosition(xOffsetLeft, yOffset);
            Console.Write(" ");
            Printer.setCursorX(xOffsetRight);
            Console.Write(" ");
        }
        #endregion

        #region Navigation Methods
        /// <summary>
        /// Navigates down one option
        /// </summary>
        /// <param name="menu">Menu to apply change to</param>
        public static void navigateDown(string[] menu)
        {
            //If the last option is not already selected,
            if (selectedOption != (menu.Length - 1))
            {
                //set the new option as selected and refresh
                deleteSelector(menu);
                selectedOption++;
                drawSelector(menu);
            }
        }

        /// <summary>
        /// Navigates up one option
        /// </summary>
        /// <param name="menu">Menu to apply change to</param>
        public static void navigateUp(string[] menu)
        {
            //If the first option is not already selected,
            if (selectedOption != 0)
            {
                //set the new option as selected and refresh
                deleteSelector(menu);
                selectedOption--;
                drawSelector(menu);
            }
        }

        /// <summary>
        /// Starts the selected option
        /// </summary>
        /// <param name="menu">Menu to read options from</param>
        public static void startOption(string[] menu)
        {
            switch (menu[selectedOption])
            {
                case "Play":
                case "Resume":
                    //Program.currStatus = Program.EStatus.Play;
                    break;
                case "Options":
                    drawOptions();
                    break;
                case "Info":
                    drawInfo();
                    break;
                case "Main Menu":
                    Program.currStatus = Program.EStatus.Menu;
                    break;
                case "Exit":
                    Program.currStatus = Program.EStatus.GameOver;
                    break;
            }
        }

        /// <summary>
        /// Set up submenu to return to main menu
        /// </summary>
        public static void setReturn()
        {
            //Print the notification in the bottom left
            Console.SetCursorPosition(0, Program.height - 1);
            Console.Write("Press ESC to return to the main menu");

            //Set up the key checker
            while (Program.currMenu == Program.EMenu.Submenu)
            {
                ConsoleKeyInfo pressedKey = Console.ReadKey();

                if (pressedKey.Key == ConsoleKey.Escape)
                {
                    Program.currMenu = Program.EMenu.Main;
                }
            }
        }
        #endregion

        #region Returners
        /// <summary>
        /// Gets the main menu options array
        /// </summary>
        /// <returns>mainMenuOptions array</returns>
        public static string[] getMainMenuOptions()
        {
            return mainMenuOptions;
        }

        /// <summary>
        /// Gets the pause menu options array
        /// </summary>
        /// <returns>pauseMenuOptions array</returns>
        public static string[] getPauseMenuOptions()
        {
            return pauseMenuOptions;
        }
        #endregion
    }
}
